using System;
using System.Collections.Generic;
using UnityEngine;

public class NavigationManager : MonoBehaviour
{
	[Serializable]
	public class ScreenGameObject
	{
		public GameObject gameObject;

		public bool isScreen;
	}

	public delegate void OnLayerChanged();

	public List<ScreenGameObject> objects = new List<ScreenGameObject>();

	public bool enableEscape = true;

	public GameObject startLayer;

	public GameObject loadingLayerPrefab;

	public LoadingLayer loading;

	protected LinkedList<GameObject> history = new LinkedList<GameObject>();

	private static NavigationManager instance_;

	public bool shouldGoBack { get; protected set; }

	public static NavigationManager instance
	{
		get
		{
			return instance_;
		}
	}

	public bool loadingOver { get; protected set; }

	public static event OnLayerChanged onLayerChanged;

	public GameObject GetObject(string name)
	{
		foreach (ScreenGameObject @object in objects)
		{
			if (@object.gameObject.name == name)
			{
				return @object.gameObject;
			}
		}
		return null;
	}

	public T GetObject<T>() where T : MonoBehaviour
	{
		foreach (ScreenGameObject @object in objects)
		{
			if (@object != null)
			{
				T component = @object.gameObject.GetComponent<T>();
				if (component != null)
				{
					return component;
				}
			}
		}
		return (T)null;
	}

	protected virtual void Init()
	{
	}

	public void Start()
	{
		instance_ = this;
		Init();
		if (loading == null)
		{
			GameObject gameObject = UnityEngine.Object.Instantiate(loadingLayerPrefab);
			Transform transform = gameObject.transform;
			transform.parent = base.transform.parent;
			transform.localScale = Vector3.one;
			transform.localPosition = Vector3.zero;
			loading = gameObject.GetComponent<LoadingLayer>();
		}
		loading.gameObject.SetActive(true);
		loading.FadeFromTo(1f, 0f, null);
		OnLoadingOver();

	}
    protected virtual void OnLoadingOver()
	{
		if (startLayer != null)
		{
			Push(startLayer);
		}
		loadingOver = true;
	}

	public void OnDestroy()
	{
		instance_ = null;
	}

	public GameObject TopLayer()
	{
		if (history.Count == 0)
		{
			return null;
		}
		return history.Last.Value;
	}

	public void PushModal(GameObject newLayer)
	{
		Debug.Log("PushModal " + newLayer.name);
		Push(newLayer, true, true);
	}

	public void Push(GameObject layer, bool activate = true)
	{
		Debug.Log("Pushed " + layer.name);
		Push(layer, false, activate);
	}

	public void PushLayers(List<GameObject> layers, bool shouldEnableLast)
	{
		for (int i = 0; i < layers.Count; i++)
		{
			bool activate = shouldEnableLast && i == layers.Count - 1;
			Push(layers[i], activate);
		}
	}

	public void ReplaceOnTop(GameObject newLayer, bool activate = true)
	{
		if (!(newLayer == null) && !(newLayer == TopLayer()))
		{
			Debug.Log("Layer pushed " + newLayer.name);
			if (history.Count > 0)
			{
				GameObject value = history.Last.Value;
				OnLeave(value);
				value.SetActive(false);
			}
			history.RemoveLast();
			history.AddLast(newLayer);
			if (activate)
			{
				newLayer.SetActive(true);
				OnEnter(newLayer);
			}
			if (NavigationManager.onLayerChanged != null)
			{
				NavigationManager.onLayerChanged();
			}
		}
	}

	public void Push(GameObject newLayer, bool isModal, bool activate)
	{
		if (newLayer == null || newLayer == TopLayer())
		{
			return;
		}
		Debug.Log("Layer pushed " + newLayer.name);
		if (history.Count > 0)
		{
			GameObject value = history.Last.Value;
			OnLeave(value);
			if (!isModal)
			{
				value.SetActive(false);
			}
		}
		history.AddLast(newLayer);
		if (activate)
		{
			newLayer.SetActive(true);
			OnEnter(newLayer);
		}
		if (NavigationManager.onLayerChanged != null)
		{
			NavigationManager.onLayerChanged();
		}
	}

	public bool ContainsLayer(GameObject layer)
	{
		foreach (GameObject item in history)
		{
			if (item == layer)
			{
				return true;
			}
		}
		return false;
	}

	public void Pop(bool force = false, bool activateNextLayer = true)
	{
		if (history.Count < 1 || (history.Count <= 1 && !force))
		{
			return;
		}
		GameObject value = history.Last.Value;
		history.RemoveLast();
		OnLeave(value);
		value.SetActive(false);
		if (history.Count < 1)
		{
			if (NavigationManager.onLayerChanged != null)
			{
				NavigationManager.onLayerChanged();
			}
		}
		else if (activateNextLayer)
		{
			GameObject value2 = history.Last.Value;
			value2.gameObject.SetActive(true);
			OnEnter(value2);
			if (NavigationManager.onLayerChanged != null)
			{
				NavigationManager.onLayerChanged();
			}
		}
	}

	private void OnLeave(GameObject obj)
	{
		if (!(obj == null))
		{
			UILayer component = obj.GetComponent<UILayer>();
			if (component != null)
			{
				component.OnLeave();
			}
		}
	}

	private void OnEnter(GameObject obj)
	{
		if (!(obj == null))
		{
			UILayer component = obj.GetComponent<UILayer>();
			if (component != null)
			{
				component.OnEnter();
			}
		}
	}

	public int HistorySize()
	{
		return history.Count;
	}

	public void ReloadActiveLayer()
	{
		GameObject value = history.Last.Value;
		value.SetActive(false);
		value.SetActive(true);
		OnEnter(value);
	}

	public virtual void Update()
	{
		shouldGoBack = Input.GetKeyDown(KeyCode.Escape) && enableEscape;
	}
}
